fix format vector consistency issues (#422)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Wed, 20 Nov 2019 17:57:48 +0000 (10:57 -0700)
committerGitHub <noreply@github.com>
Wed, 20 Nov 2019 17:57:48 +0000 (10:57 -0700)
* fix format vector consistency issues.

* fix leaks in sort_and_unify_vecs.

* fix vec init for msvc2015.

* Revert "fix vec init for msvc2015."

This reverts commit 02b85801ee4d1de24101713fbd85c33238da6183.

* Revert "fix leaks in sort_and_unify_vecs."

This reverts commit d634c21f9f7767d198750e61ba426eb7850127a9.

* only validate formats for real types.

12 files changed:
defs.h
globalsat_sport.cc
itracku.cc
main.cc
navicache.cc
pocketfms_fp.cc
saroute.cc
testo.d/validate_formats.test [new file with mode: 0644]
tpo.cc
vecs.cc
vpl.cc
yahoo.cc

diff --git a/defs.h b/defs.h
index ebfc32a3e518c4cae2292b21cab0b52ef3815664..67ac6a90e613edfa075a95a6e85420b992377af7 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1071,6 +1071,7 @@ void assign_option(const char* vecname, arglist_t* ap, const char* val);
 void disp_vec_options(const char* vecname, arglist_t* ap);
 void disp_vecs();
 void disp_vec(const char* vecname);
+int validate_formats();
 void init_vecs();
 void exit_vecs();
 void disp_formats(int version);
index 0a0063e5a44c00ae3c4437c08257993b2b0ae676..eb69f07f635ccfe6a6f87bc445e35220045b9f40 100644 (file)
@@ -48,9 +48,9 @@ static void* serial_handle;
 static bool isSizeSwapped;
 
 static char* showlist = nullptr;               // if true show a list instead of download tracks
-static char* track = nullptr;                     // if not 0 only download this track, if 0 download all
+static char* track = nullptr;                  // if not 0 only download this track, if 0 download all
 
-static char* opt_dump_file = nullptr;              // dump raw data to this file (optional)
+static char* opt_dump_file = nullptr;          // dump raw data to this file (optional)
 static char* opt_input_dump_file = nullptr;    // if true input is from a dump-file instead of serial console
 static gbfile* dumpfile = nullptr;             // used for creating bin/RAW datadump files, useful for testing
 static gbfile* in_file = nullptr;              // used for reading from bin/RAW datadump files, useful for testing
@@ -423,16 +423,6 @@ rd_init(const QString& fname)
   globalsat_probe_device();
 }
 
-static void
-wr_init(const QString& fname)
-{
-  if (global_opts.debug_level > 1) {
-    printf(MYNAME " wr_init()\n");
-  }
-  serial_init(qPrintable(fname));
-}
-
-
 static void
 rd_deinit()
 {
@@ -455,18 +445,8 @@ rd_deinit()
   }
 }
 
-static void
-wr_deinit()
-{
-  if (global_opts.debug_level > 1) {
-    printf(MYNAME " wr_deinit()\n");
-  }
-  serial_deinit();
-}
-
 static void track_read();
 
-
 static void
 waypoint_read()
 {
@@ -830,39 +810,22 @@ data_read()
 
 // This used the serial communication to the watch
 ff_vecs_t globalsat_sport_vecs = {
-  ff_type_serial,              //type
-  FF_CAP_RW_ALL,               //cap[3]
-  rd_init,                     //rd_init
-  wr_init,                     //wr_init
-  rd_deinit,                   //rd_deinit
-  wr_deinit,                   //wr_deinit
-  data_read,                   //read
-  nullptr,                     //write
-  nullptr,                             //exit
-  globalsat_args,              //args
-  CET_CHARSET_ASCII, 0         //encode,fixed_encode
-  //NULL                   //name dynamic/internal?
-  , NULL_POS_OPS,
-  nullptr
-};
-
-// This reads from a RAW dump bile from a watch
-// Useful for testing generated dumpfile with
-// gpsbabel -i globalsat,dump-file=<dumpfilename> -f /dev/ttyUSB0 -o gpx,garminextensions -F <1:st gpx file name>
-// gpsbabel -i globalsat-bin -f <dumpfilename> -o gpx,garminextensions -F <2:nd gpx file name>
-ff_vecs_t globalsat_sport_fvecs = {
-  ff_type_serial,              //type
-  FF_CAP_RW_ALL,               //cap[3]
-  rd_init,                     //rd_init
-  wr_init,                     //wr_init
-  rd_deinit,                   //rd_deinit
-  wr_deinit,                   //wr_deinit
-  data_read,                   //read
-  nullptr,                     //write
-  nullptr,                             //exit
-  globalsat_args,              //args
-  CET_CHARSET_ASCII, 0         //encode,fixed_encode
-  //NULL                   //name dynamic/internal?
-  , NULL_POS_OPS,
+  ff_type_serial,                      // type
+  {                                                                            // cap
+    ff_cap_none,                       // waypoints
+    ff_cap_read,                       // tracks
+    ff_cap_none,                       // routes
+  },
+  rd_init,                                             // rd_init
+  nullptr,                                             // wr_init
+  rd_deinit,                                   // rd_deinit
+  nullptr,                                             // wr_deinit
+  data_read,                                   // read
+  nullptr,                                             // write
+  nullptr,                                             // exit
+  globalsat_args,                      // args
+  CET_CHARSET_ASCII,   // encode
+  0,                                                                   // fixed_encode
+  NULL_POS_OPS,                                // position_ops
   nullptr
 };
index 9f3258e1c9a6d85c8e180df7c18c99ebc78cf8ef..01fa71772786948cff8ce4c471d3c28a4bb9e54e 100644 (file)
   ./gpsbabel -i itracku -f com14 -o gpx -F out.gpx
 
  */
+#include <cmath>                   // for lround, round, floor
+#include <cstdarg>                 // for va_end, va_list, va_start
+#include <cstdio>                  // for fprintf, stderr, SEEK_END, fflush, sscanf, vfprintf
+#include <cstdint>
+#include <cstring>                 // for memcpy, strcmp, strlen, strncmp
+#include <ctime>                   // for gmtime
+
+#include <QtCore/QByteArray>       // for QByteArray
+#include <QtCore/QDate>            // for QDate
+#include <QtCore/QDateTime>        // for QDateTime
+#include <QtCore/QString>          // for QString
+#include <QtCore/QTime>            // for QTime
+#include <QtCore/Qt>               // for UTC
+#include <QtCore/QtGlobal>         // for qPrintable
+
 #include "defs.h"
-#include "gbser.h"
-#include <cctype>
-#include <cmath>
-#include <cstdio>
+#include "gbser.h"                 // for gbser_read_line, gbser_write, gbser_deinit, gbser_flush, gbser_init, gbser_is_serial, gbser_read_wait, gbser_ERROR, gbser_OK
+#include "gbfile.h"                // for gbfile, gbfclose, gbfopen, gbfseek, gbfread, gbfwrite, gbftell, gbsize_t
+#include "src/core/datetime.h"     // for DateTime
+
 
 #define MYNAME "itracku"
 
@@ -243,7 +258,7 @@ deg_to_deg_min(double x)
 
   return
     (uint32_t)d * 1000000 + // multiply integer degrees to shift it to the right digits.
-    (uint32_t)(f * 600000.0) + // multiply fractional part to convert to minutes and to to shift it to the right digits.
+    (uint32_t)round((f * 600000.0)) + // multiply fractional part to convert to minutes and to to shift it to the right digits.
     ((sign > 0) ? 0 : 0x80000000); // add 0x80000000 for negative degrees
 }
 
@@ -304,7 +319,7 @@ to_itracku_data_record(const Waypoint* wp, itracku_data_record* d)
   le_write32(d->longitude, deg_to_deg_min(wp->longitude));
   le_write32(d->latitude, deg_to_deg_min(wp->latitude));
   le_write32(d->creation_time, encode_itracku_time(wp->creation_time.toTime_t()));
-  d->speed = MPS_TO_KNOTS(wp->speed);
+  d->speed = round(MPS_TO_KNOTS(wp->speed));
   le_write16(d->altitude, wp->altitude);
   d->flag = 0xff;
 }
@@ -751,11 +766,9 @@ itracku_rt_deinit()
 
 /**************************************************************************/
 
-// capabilities below means: we can only read and write waypoints
-// please change this depending on your new module
 
 ff_vecs_t itracku_vecs = {
-  ff_type_file,
+  ff_type_serial,
   {
     ff_cap_read /* waypoints */,
     ff_cap_read /* tracks */,
@@ -766,7 +779,7 @@ ff_vecs_t itracku_vecs = {
   itracku_rd_deinit,
   nullptr,
   itracku_read,
-  itracku_write,
+  nullptr,
   itracku_exit,
   itracku_args,
   CET_CHARSET_ASCII, 0, /* ascii is the expected character set */
diff --git a/main.cc b/main.cc
index 6c7c6a2fe0204f3ef0e9cd4a8a4f34e26095d41c..f87a31fbd2fe9972cbfe537d80ea885aa289bd81 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -448,8 +448,14 @@ run(const char* prog_name)
         warning(MYNAME ": QTextCodec::codecForLocale() is %s, mib %d\n",
                 defaultcodec->name().constData(),defaultcodec->mibEnum());
       }
-
       break;
+
+    /*
+     * Undocumented '-@' option for test.
+     */
+    case '@':
+      return validate_formats();
+
     /*
      * Undocumented '-vs' option for GUI wrappers.
      */
index d333480eed73f4e4d622cdea8470304961c177c2..835e4e9cf0a4ff53324aa46f7efe63e08a855ce0 100644 (file)
@@ -204,31 +204,15 @@ nav_rd_deinit()
 {
 }
 
-static void
-nav_wr_init(const QString&)
-{
-  fatal(MYNAME ": Does not support writing Navicache files.\n");
-}
-
-static void
-nav_wr_deinit()
-{
-}
-
-static void
-nav_write()
-{
-}
-
 ff_vecs_t navicache_vecs = {
   ff_type_file,
   { ff_cap_read, ff_cap_none, ff_cap_none },
   nav_rd_init,
-  nav_wr_init,
+  nullptr,
   nav_rd_deinit,
-  nav_wr_deinit,
+  nullptr,
   nav_read,
-  nav_write,
+  nullptr,
   nullptr,
   nav_args,
   CET_CHARSET_UTF8, 0  /* CET-REVIEW */
index 0f959acdf462b355da0fa18c0d296e8472a01428..10bb7baed9a3941d84fe279a7222f756d436d505 100644 (file)
@@ -82,12 +82,6 @@ rd_deinit()
   xml_deinit();
 }
 
-static void
-wr_init(const QString&)
-{
-  fatal("Writing file of type %s is not supported\n", MYNAME);
-}
-
 void   wpt_s(xg_string, const QXmlStreamAttributes*)
 {
   if (isFirst == 1) {
@@ -187,7 +181,7 @@ ff_vecs_t pocketfms_fp_vecs = {
     ff_cap_read        /* routes */
   },
   rd_init,
-  wr_init,
+  nullptr,
   rd_deinit,
   nullptr,
   data_read,
index 1ca344f54bc9dc6eb34facc6f7cbbf0ceac91397..75cfe6cdd1a973eda7174d8eef5b095a35bd7754 100644 (file)
@@ -447,17 +447,11 @@ my_read()
 
 }
 
-static void
-wr_init(const QString&)
-{
-  fatal(MYNAME ":Not enough information is known about this format to write it.\n");
-}
-
 ff_vecs_t saroute_vecs = {
   ff_type_file,
   { ff_cap_none, ff_cap_read, ff_cap_none},
   rd_init,
-  wr_init,
+  nullptr,
   rd_deinit,
   nullptr,
   my_read,
diff --git a/testo.d/validate_formats.test b/testo.d/validate_formats.test
new file mode 100644 (file)
index 0000000..4ff1c00
--- /dev/null
@@ -0,0 +1,2 @@
+gpsbabel -@
+
diff --git a/tpo.cc b/tpo.cc
index a90af11a4cf550946a118c3d7dca8cfdc6c8c6ac..dcb8a97562e029f285809e09a6ba449fa9978153 100644 (file)
--- a/tpo.cc
+++ b/tpo.cc
 #define MYNAME "TPO"
 
 static char* dumpheader = nullptr;
+#ifdef ENABLE_TPO_WRITE
 static char* output_state = nullptr;
+#endif
 
-/*
+#ifdef ENABLE_TPO_WRITE
 static
 arglist_t tpo2_args[] = {
        { "dumpheader", &dumpheader, "Display the file header bytes",
@@ -103,7 +105,7 @@ arglist_t tpo2_args[] = {
          "CA", ARGTYPE_STRING, ARG_NOMINMAX} ,
        ARG_TERMINATOR
 };
-*/
+#else
 //
 // Note that we've disabled the write capabilities for the tpo2
 // format at present.  The "testo" tests were failing on some
@@ -115,6 +117,7 @@ static
 arglist_t tpo2_args[] = {
   ARG_TERMINATOR
 };
+#endif
 
 static
 arglist_t tpo3_args[] = {
@@ -123,8 +126,10 @@ arglist_t tpo3_args[] = {
 
 
 static gbfile* tpo_file_in;
+static double track_length;
+
+#ifdef ENABLE_TPO_WRITE
 static gbfile* tpo_file_out;
-//static short_handle mkshort_handle;
 
 static double output_track_lon_scale;
 static double output_track_lat_scale;
@@ -132,10 +137,10 @@ static double output_track_lat_scale;
 static unsigned int track_out_count;
 static double first_track_waypoint_lat;
 static double first_track_waypoint_lon;
-static double track_length;
 static double last_waypoint_x;
 static double last_waypoint_y;
 static double last_waypoint_z;
+#endif
 
 /*******************************************************************************/
 /*                                      READ                                   */
@@ -1337,7 +1342,7 @@ tpo_read()
 
 
 
-
+#ifdef ENABLE_TPO_WRITE
 /*******************************************************************************/
 /*                                     WRITE                                   */
 /*******************************************************************************/
@@ -1374,8 +1379,6 @@ tpo_read()
 static void
 tpo_write_file_header()
 {
-  // this assertion will quiet gcc 7.3 warnings about output_state in the strncmp calls
-  // warning: argument 2 null where non-null expected [-Wnonnull]
   assert(output_state != nullptr);
 
   /* force upper-case state name */
@@ -1802,18 +1805,34 @@ tpo_write()
   track_out_count = 0;
   track_disp_all(tpo_track_hdr, tpo_track_tlr, tpo_track_disp);
 }
+#endif // ENABLE_TPO_WRITE
 
 /* TPO 2.x format can read tracks only */
 ff_vecs_t tpo2_vecs = {
   ff_type_file,   /* ff_type_internal */
-  /*    { ff_cap_none | ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none | ff_cap_none }, */
+#ifdef ENABLE_TPO_WRITE
+  { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none },
+#else
   { ff_cap_none, ff_cap_read,  ff_cap_none },
+#endif
   tpo_rd_init,
+#ifdef ENABLE_TPO_WRITE
   tpo_wr_init,
+#else
+  nullptr,
+#endif
   tpo_rd_deinit,
+#ifdef ENABLE_TPO_WRITE
   tpo_wr_deinit,
+#else
+  nullptr,
+#endif
   tpo_read,
+#ifdef ENABLE_TPO_WRITE
   tpo_write,
+#else
+  nullptr,
+#endif
   nullptr,
   tpo2_args,
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
@@ -1826,11 +1845,11 @@ ff_vecs_t tpo3_vecs = {
   ff_type_file,   /* ff_type_internal */
   { ff_cap_read, ff_cap_read, ff_cap_read },
   tpo_rd_init,
-  tpo_wr_init,
+  nullptr,
   tpo_rd_deinit,
-  tpo_wr_deinit,
+  nullptr,
   tpo_read,
-  tpo_write,
+  nullptr,
   nullptr,
   tpo3_args,
   CET_CHARSET_ASCII, 0 /* CET-REVIEW */
diff --git a/vecs.cc b/vecs.cc
index 6ec8a8816751012cbc15fdb5ba3efa4fbccb8971..2d5d0889fb33a4e0d44e62867223d4d9152b5386 100644 (file)
--- a/vecs.cc
+++ b/vecs.cc
@@ -1700,3 +1700,91 @@ disp_formats(int version)
     ;
   }
 }
+
+static bool
+validate_vec(const vecs_t* vec)
+{
+  bool ok = true;
+
+  if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write)) {
+    if (vec->vec->wr_init != nullptr) {
+      printf("ERROR no write capability but non-null wr_init %s\n", vec->name);
+      ok = false;
+    }
+  }
+  if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read)) {
+    if (vec->vec->rd_init != nullptr) {
+      printf("ERROR no read capbility but non-null rd_init %s\n", vec->name);
+      ok = false;
+    }
+  }
+  if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write) {
+    if (vec->vec->wr_init == nullptr) {
+      printf("ERROR write capability but null wr_init %s\n", vec->name);
+      ok = false;
+    }
+  }
+  if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read) {
+    if (vec->vec->rd_init == nullptr) {
+      printf("ERROR read capability but null rd_init %s\n", vec->name);
+      ok = false;
+    }
+  }
+
+  if (vec->vec->wr_init != nullptr) {
+    if (vec->vec->write == nullptr) {
+      printf("ERROR nonnull wr_init but null write %s\n", vec->name);
+      ok = false;
+    }
+    if (vec->vec->wr_deinit == nullptr) {
+      printf("ERROR nonnull wr_init but null wr_deinit %s\n", vec->name);
+      ok = false;
+    }
+  }
+  if (vec->vec->wr_init == nullptr) {
+    if (vec->vec->write != nullptr) {
+      printf("ERROR null wr_init with non-null write %s\n", vec->name);
+      ok = false;
+    }
+    if (vec->vec->wr_deinit != nullptr) {
+      printf("ERROR null wr_init with non-null wr_deinit %s\n", vec->name);
+      ok = false;
+    }
+  }
+
+  if (vec->vec->rd_init != nullptr) {
+    if (vec->vec->read == nullptr) {
+      printf("ERROR nonnull rd_init but null read %s\n", vec->name);
+      ok = false;
+    }
+    if (vec->vec->rd_deinit == nullptr) {
+      printf("ERROR nonnull rd_init but null rd_deinit %s\n", vec->name);
+      ok = false;
+    }
+  }
+  if (vec->vec->rd_init == nullptr) {
+    if (vec->vec->read != nullptr) {
+      printf("ERROR null rd_init with non-null read %s\n", vec->name);
+      ok = false;
+    }
+    if (vec->vec->rd_deinit != nullptr) {
+      printf("ERROR null rd_init with non-null rd_deinit %s\n", vec->name);
+      ok = false;
+    }
+  }
+
+  return ok;
+}
+
+int validate_formats()
+{
+  bool ok = true;
+
+  const vecs_t* vec = vec_list;
+  while (vec->vec) {
+    ok = validate_vec(vec) && ok;
+    vec++;
+  }
+
+  return ok? 0 : 1;
+}
diff --git a/vpl.cc b/vpl.cc
index 8fe053f2d1f1bf0ee3a68a34b19b2c3c9a4521d8..5a575745c5295958996ebe26f58848b963eabc41 100644 (file)
--- a/vpl.cc
+++ b/vpl.cc
@@ -155,12 +155,6 @@ vpl_read()
   }
 }
 
-static void
-vpl_wr_init(const QString&)
-{
-  fatal("Writing file of type %s is not support\n", MYNAME);
-}
-
 /*******************************************************************************
 * Local Functions
 *******************************************************************************/
@@ -222,7 +216,7 @@ ff_vecs_t vpl_vecs = {
     ff_cap_none                /* routes */
   },
   vpl_rd_init,
-  vpl_wr_init,
+  nullptr,
   vpl_rd_deinit,
   nullptr,
   vpl_read,
index cd2572a439390823b5d394ddd1b1d59d0b2c4504..3e9bbf350feeed4b8e50844ca5b1b9de5cb769b0 100644 (file)
--- a/yahoo.cc
+++ b/yahoo.cc
@@ -72,12 +72,6 @@ yahoo_rd_deinit()
   xml_deinit();
 }
 
-static void
-yahoo_wr_init(const QString&)
-{
-  fatal("Writing file of type %s is not supported\n", MYNAME);
-}
-
 void   wpt_s(xg_string, const QXmlStreamAttributes*)
 {
   wpt_tmp = new Waypoint;
@@ -109,9 +103,9 @@ void        wpt_addr(xg_string args, const QXmlStreamAttributes*)
 
 ff_vecs_t yahoo_vecs = {
   ff_type_file,
-  { ff_cap_read },
+  { ff_cap_read, ff_cap_none, ff_cap_none },
   yahoo_rd_init,
-  yahoo_wr_init,
+  nullptr,
   yahoo_rd_deinit,
   nullptr,
   yahoo_read,